package com.codejoys.ssm.security;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.core.GrantedAuthority;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.web.authentication.WebAuthenticationDetailsSource;
import org.springframework.stereotype.Component;
import org.springframework.web.filter.OncePerRequestFilter;

import javax.servlet.FilterChain;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.util.Collection;

@Component
public class JwtAuthenticationFilter extends OncePerRequestFilter {
	@Autowired
	private JwtTokenProvider tokenProvider;

	@Override
	protected void doFilterInternal(
            HttpServletRequest request, HttpServletResponse response, FilterChain filterChain)
			throws ServletException, IOException {
		// 从请求头里面解析出来jwt token
		// eyJhbGciOiJIUzI1NiJ9.eyJzdWIiOiJ3YW5nd3UiLCJleHAiOjE1Mzg0NDc2MTcsImlhdCI6MTUzODQ0NzAxMn0.iCR1H2MFLkTasfIj8adR0BxqKXDibZK-T7uX1sCjvY0
		String token = tokenProvider.extractToken(request);
		
		if (tokenProvider.validate(token)) {	// 验证token的合法性
			//解析token， 取用户名、角色
			UserDetails details = tokenProvider.getUserDetailsFromToken(token);
			String userName = details.getUsername();
			Collection<? extends GrantedAuthority> authorities = details.getAuthorities();
			
			UsernamePasswordAuthenticationToken authentication = null;
			if (userName != null && userName.length() != 0) {
				// 生成认证信息		
				authentication = new UsernamePasswordAuthenticationToken(userName, null, authorities);

				// TODO remove
				authentication.setDetails(new WebAuthenticationDetailsSource().buildDetails(request));
			}
			
			// 把认证信息存入SecurityContextHolder，后续处理就能知道当前用户是谁
			// 后面其它的过滤器会取这个认证信息  如果取不到，就会报认证失败
			SecurityContextHolder.getContext().setAuthentication(authentication);
		}

		
		filterChain.doFilter(request, response);
	}
}
